import json

import openai

openai.api_key = "sk-L3KqNC2genjOyePnMJJUFRTiJvipiLzONQz25yc77LBRYKz2"
openai.api_base = "https://api.chatanywhere.com.cn/v1"



def gpt_35_api_stream(messages: list):
    try:
        response = openai.ChatCompletion.create(
            model='gpt-3.5-turbo',
            messages=messages,
            stream=True,
        )
        completion = {'role': '', 'content': ''}
        for event in response:
            if event['choices'][0]['finish_reason'] == 'stop':
                print(f'收到的完成数据: {completion}')
                break
            for delta_k, delta_v in event['choices'][0]['delta'].items():
                # print(f'流响应数据: {delta_k} = {delta_v}')
                completion[delta_k] += delta_v
        messages.append(completion)  # 直接在传入参数 messages 中追加消息
        return (True, '')
    except Exception as err:
        return (False, f'OpenAI API 异常: {err}')


def use_Api(content):
    messages = [
        {"role": "system", "content": "你是一名人工智能助手，负责以如下格式修改、补全、分类已有的编程题目"},
        {"role": "user",
         "content": "请以相同json格式补全并修改、扩充如下题目，包括tags（分类，只包括数学、字符串、动态规划），content(题目内容，需要补全完整，修正错误，扩充，存在输入输出格式)，solution（解决代码，C++），test_case（测试点）。题目：在一个n×n的矩阵里，有若干个敌人，你的弹珠可以摧毁敌人，但只能攻击你所在的行、列里的所有敌人，现在请你选择一个你的位置，使得能击杀的敌人最多"},
        {"role": "assistant",
         "content": "{\"tags\": \"动态规划\",\"content\": \"MedalPluS 和他的小伙伴 NOIRP 发掘了一个骨灰级别的游戏——超级弹珠。\\n游戏的内容是：在一个 n×n 的矩阵里，有若干个敌人，你的弹珠可以摧毁敌人，但只能攻击你所在的行、列里的所有敌人，然后你就可以获得他们的分数之和，现在请你选择一个你的位置，使得能击杀的敌人最多，注意，你不能和敌人在一个地方。\\n输入格式\\n输入有两行，第一行一个正整数 n，接下来n 行，每行n 列，如果有敌人则为一个正整数，否则为0\\n输出格式\\n输出共一行，最多分数，如果连你的容身之地都没有，请输出Bad Game! 样例输入：\\n4\\n1 1 1 0\\n1 1 1 1\\n1 1 1 1\\n0 1 1 1\\n样例输出：\\n6\",\"solution\": \"#include<bits/stdc++.h>     //万能头文件 \\nusing namespace std;\\nint main(){\\n	int n;\\n	cin>>n;\\n	int a[n][n],sum[n*n]={0};      //sum用来记录矩阵每一个容身之处的分数 \\n	for(int i=0;i<n;i++){\\n		for(int j=0;j<n;j++){\\n			cin>>a[i][j];\\n		}\\n	}\\n	int aa=0;              //因为不知道一共有多少个sum，所以用aa计数 \\n	for(int i=0;i<n;i++){       //在矩阵中找无敌人的地点 \\n		for(int j=0;j<n;j++){\\n			if(a[i][j]==0){\\n				for(int k=0;k<n;k++){\\n					sum[aa]+=a[k][j];   //统计所在列获得的分数 \\n				}\\n				for(int k=0;k<n;k++){\\n					sum[aa]+=a[i][k];   //统计所在行获得的分数 \\n				}\\n				aa++;      //统计完一个点的分数后使用数组的下一位进行存储 \\n			}\\n		}\\n	}         //sort真好用 \\n	sort(sum,sum+n*n,greater<int>());     //把每个点获得的分数从大到小排序 \\n	cout<<sum[0]<<endl;         //输出最大分数 \\n	return 0;\\n}\",\"test_case\": \"测试点1：\\n5\\n0 1 1 1 1\\n1 0 0 0 0\\n1 0 0 0 0\\n1 0 0 0 0\\n1 0 0 0 0\\n正确输出：\\n8\\n\\n测试点2：\\n5\\n0 0 1 1 1\\n0 0 0 0 0\\n0 0 1 0 0\\n0 0 1 0 0\\n1 0 0 0 0\\n正确输出：\\n5\"}"},
        {"role": "user",
         "content": "请以相同json格式补全并修改如下题目，包括tags（分类，只包括数学、字符串、动态规划），content(题目内容，需要补全完整，修正错误，存在输入输出格式)，solution（解决代码，C++），test_case（测试点）。" + content}
    ]
    # 信息会在gpt_35_api_stream(messages) 返回值里面
    # 读取即可  |  生成时间可能要一分钟
    gpt_35_api_stream(messages)
    #print(messages[4])
    ##返回的第一个cotent是字符串，要load一下
    #print(messages[4].get('content'))
    #print(messages[4].get('content').get('content'))
    originD = messages[4].get('content')
    #防止一个\
    try:
        print(originD)
        return json.loads(originD,strict=False)
    except json.decoder.JSONDecodeError:
        print("decode error!")
        target = deal_json_invaild(messages[4].get('content'))
        print(target)
        return json.loads(target,strict=False)
        return use_Api(content)

    #print(messages[4]['content']['content'])

#处理json字符串中含有非法的引号和\！
def deal_json_invaild(data):
    data = data.replace('\\','\\\\')
    data = data.replace("\\\\n", "\\n").replace("\\\\r", "\\r").replace("\\\\n\\\\r", "\\n\\r") \
        .replace("\\\\r\\\\n", "\\r\\n") \
        .replace("\\\\t", "\\t")

    data = data.replace('": "', '&&testPassword&&')\
        .replace('","', "$$testPassword$$")\
        .replace('{"', "@@testPassword@@")\
        .replace('"}', "**testPassword**")
    #print(data)

    data = data.replace('"', r'\"')\
        .replace('&&testPassword&&', '": "').replace('$$testPassword$$', '", "').replace('@@testPassword@@', '{"').replace('**testPassword**', '"}')
    #print(data)
    return data

# 使用举例
if __name__ == '__main__':
    # 假设题目不完整，会补全
    content1 = "题目: 有 n 个盒子和 n 种颜色，每个盒子装有 k 个红球或 w 个白球（不重复）。"
    use_Api(content1)